#include<iostream>
#include<string>
#include<unistd.h>
#include<vector>
#include<cstdlib>
#include<functional>
#include<sys/types.h>
#include<sys/wait.h>



//子进程
class channel
{
public:
  channel(int cmdfd, pid_t slaverid, const std::string& processname)
    :_cmdfd(cmdfd)
    ,_slaverid(slaverid)
    ,_processname(processname)
  {}

  int _cmdfd; //发送任务的描述符
  pid_t _slaverid; //接收任务的子进程
  std::string _processname; //子进程名字，方便打印日志
};

//添加任务
template<class FN>
class Task
{
public:
  Task()
  {}
  
  std::function<FN>& get(size_t n)
  {
    return _task[n];
  }

  bool add(FN& task)
  {

    _task.push_back(std::function<FN>(task));
    return true;
  }

  bool erase(size_t cmdfd)
  {
    if (cmdfd >= _task.size())
    {
      return false;
    }

    _task.erase(_task.begin() + cmdfd);
    return true;
  }

  size_t size()
  {
    return _task.size();
  }

private:
 std::vector<std::function<FN>> _task;
};


//任务列表
Task<int()> ts;

//子进程执行任务
void execute(int taskid)
{
  ts.get(taskid)(); 
}



int task(int fd)
{
  //获取信息 读取
  int taskid;
  bool check = true;
  while (check)
  {
     int n = read(fd, &taskid, sizeof(int));
     if (n > 0)
     {
       //执行任务
       execute(taskid);
     }
     else if (n == 0)
     {
       break;
     }
     //无任务休眠
     sleep(5);
  }
  return 0;
}


class channels
{
public:
  
  channels(size_t n)
  {
    for (size_t i = 0; i < n; i++)
    {
      int pipefd[2];
      int n = pipe(pipefd);
      if (n == -1)
      {
        throw "channels pipe error";
      }

      pid_t id = fork();
      if (id == 0)
      {
        close(pipefd[1]);

        //任务执行
        int check = task(pipefd[0]);
        if (check == -1)
        {
          perror("");
          exit(-1);
        }
        else 
        {
          std::cout << getpid() << "sucess" << std::endl;
        }
        exit(0);
      }

      close(pipefd[0]);

      std::string name = "Process ";
      name += static_cast<char>('0' + i);

      _channels.push_back(channel(pipefd[1], id, name));
    }
  }

  channel& get(size_t n)
  {
    return _channels[n];
  }
  
  size_t size()
  {
    return _channels.size();
  }
  
  ~channels()
  {
    for (auto c : _channels)
    {
      close(c._cmdfd);
    }
  }
  std::vector<channel> _channels;
};


//加入列表的任务
int add()
{
  int ans = 0;
  for (int i = 0; i < 100; i++)
  {
    ans += i;
  }
  std::cout << ans << std::endl;

  return ans;
}

int s()
{
  std::cout << "嘻嘻哈哈的zl" << std::endl;
  return 0;
}

void disptask(channels& cha)
{
  for (size_t i = 0; i < ts.size(); i++)
  {
    size_t work = i % cha.size();
    write(cha.get(work)._cmdfd, &i, sizeof(int));

  }
}

void quetprocess(channels& cha)
{

   for (size_t i = 0; i < cha.size(); i++)
   {
     close(cha.get(i)._cmdfd);
   }

   for (size_t i = 0; i < cha.size(); i++)
   {
     waitpid(cha.get(i)._slaverid, nullptr, 0);
   }
}

int main()
{
  //轮转分配任务
  //写入信息：任务码 任务码位数
  
  //任务列表
  ts.add(add);
  ts.add(s);
  
  //申请5个子进程的
  channels cha(5);
  
  //轮转分配任务
  disptask(cha); 

  //释放资源
  quetprocess(cha);

  return 0;
}
